#pragma once
#define NOMINMAX
#include <core/sync/lock.h>
#include <qbprotocol/include/SSQBModel.h>

#include <list>
#include <map>
#include <string>
#include <utility>

#include "BondMarketStream.h"
#include "bondlib.h"
/***************************************************************************************************
 *Copyright(C),2017-2020,Sumscope
 *FileName	:  BondHisMarketStream
 *Author	:  Givins.zhu
 *Version	:  1.0
 *Date		:  2017/10/24
 *Desc		:  历史成交统计功能
 *Relation :
 *Module   :
 *Others   :
 *Function :
 *History	:
 *Email    :  Givins.zhu@sumscope.com
 ***************************************************************************************************/

/************************************************************************/
/* 历史和当天成交数据的统一格式                                               */
/************************************************************************/
class S_BONDLIB_EXPORT CFormatMarketStreamInfo {
 public:
  void InitialData() {
    m_dealTime = 0;
    m_bHistory = false;
    m_BrokerID[0] = '\0';
    m_bondkey[0] = '\0';
    m_listedmarket[0] = '\0';
    m_issuerRating[0] = '\0';
    m_issuerBondRating[0] = '\0';
    m_exercise[0] = '\0';
    m_cdcExercise[0] = '\0';
    m_cdcExerciseExtra[0] = '\0';
    m_zzExercise[0] = '\0';
    m_zzExerciseExtra[0] = '\0';
    m_PreClose[0] = '\0';
    m_quotetype[0] = '\0';
    m_indexID = 0;
    m_type = 0;
    m_sCDCRating[0] = '\0';
    m_sCSIRating[0] = '\0';
    m_sCBRRating[0] = '\0';
    m_sCSIDefaultRating[0] = '\0';
    m_sCouponRate[0] = '\0';

    m_price = m_duration = m_advYesYeild = m_cdcValuation =
        m_cdcValuationExtra = m_zzValuation = m_zzValuationExtra = m_amount =
            0.0f;
  }
  bool IsDealStatusCanceled() {
    if (m_bHistory)
      return false;
    else
      return m_mktStreamInfo.IsDealStatusCanceled();
  }
  CFormatMarketStreamInfo() { InitialData(); }
  CFormatMarketStreamInfo(const MarketStreamInfo& info) {
    m_mktStreamInfo = info;
    m_indexID = info.m_indexID;
    m_dealTime = std::max(info.m_create_time, info.m_modify_time);
    m_type = atoi(info.m_operate);
    FIELDCOPY(m_bondkey, info.m_body.m_bondkey);
    FIELDCOPY(m_listedmarket, info.m_body.m_listedmarket);
    FIELDCOPY(m_BrokerID, info.m_company_id);
    FIELDCOPY(m_quotetype, info.m_body.m_quotetype);
    m_bHistory = false;
  }
  CFormatMarketStreamInfo& operator=(const MarketStreamInfo& info) {
    m_mktStreamInfo = info;
    m_indexID = info.m_indexID;
    m_dealTime = std::max(info.m_create_time, info.m_modify_time);
    m_type = atoi(info.m_operate);
    FIELDCOPY(m_bondkey, info.m_body.m_bondkey);
    FIELDCOPY(m_listedmarket, info.m_body.m_listedmarket);
    FIELDCOPY(m_BrokerID, info.m_company_id);
    FIELDCOPY(m_quotetype, info.m_body.m_quotetype);
    m_bHistory = false;
    return *this;
  }

  const bool operator<(const CFormatMarketStreamInfo& obj) const {
    return (m_dealTime > obj.m_dealTime);
  }

  bool IsCleanPrice() const { return strcmp(m_quotetype, "1") == 0; }  // 净价
  bool IsFullPrice() const { return strcmp(m_quotetype, "2") == 0; }   // 全价

  MarketStreamInfo m_mktStreamInfo;

  float m_price;        // 成交价格
  float m_yield;        // 收益率
  float m_cleanPrice;   // 净价
  float m_duration;     // 久期
  float m_advYesYeild;  // 昨日平均 5家broker

  float m_amount;           // 债券余额
  time_t m_dealTime;        // 成交时间
  char m_BrokerID[32 + 1];  // BrokerID,

  char m_bondkey[32 + 1];      // key
  char m_listedmarket[12];     // 市场代码
  char m_issuerRating[6];      // 主体评级
  char m_issuerBondRating[6];  // 债项评级

  float m_cdcValuation;       // 中债估值
  float m_cdcValuationExtra;  // 中债估值
  float m_zzValuation;        // 中证估值
  float m_zzValuationExtra;   // 中证估值

  char m_exercise[2];          // 行权到期  (0-行权 1-到期)
  char m_cdcExercise[2];       // cdc行权到期  (0-行权 1-到期)
  char m_cdcExerciseExtra[2];  // cdc行权到期  (0-行权 1-到期)

  char m_zzExercise[2];       // zz行权到期  (0-行权 1-到期)
  char m_zzExerciseExtra[2];  // zz行权到期  (0-行权 1-到期)

  char m_PreClose[32];  // 昨收
  char m_quotetype[4];  // 报价类型，0-有意向；1-净价；2-全价；3-收益率；4-利差

  int m_type;     // 成交方向
  int m_indexID;  // 历史需要转换
  /************************************************************************/
  /* 是否为历史数据                                                         */
  /************************************************************************/

  char m_sCDCRating[12];         // 中债隐含评级    5.2.0新增
  char m_sCSIRating[12];         // 中证隐含评级         5.2.0新增
  char m_sCBRRating[12];         // 中债资信评级             5.2.0新增
  char m_sCSIDefaultRating[12];  // 中证隐含违约率             5.2.0新增
  char m_sCouponRate[12];        // 票面利息

  bool m_bHistory;
};

class S_BONDLIB_EXPORT CBondHisMarketstreamDealInfo {
 public:
  /*债券信息*/
  xQBHisMarketstreamBondUnit_c m_BondInfo;
  /*成交*/
  std::list<xQBHisMarketstreamDealUnit_c> m_Deal;
};

class S_BONDLIB_EXPORT CBondHisMarketstreamDay {
 public:
  /************************************************************************/
  /* 插入债券信息集合                                                        */
  /************************************************************************/
  bool InsertBondInfoList(
      const std::list<xQBHisMarketstreamBondUnit_c>& bondStream);

  /************************************************************************/
  /* 插入债券成交集合                                                        */
  /************************************************************************/
  bool InsertBondDealList(std::list<xQBHisMarketstreamDealUnit_c>);

  /*判断是否NCD券*/
  bool IsNCD(const std::string& stCombondKey);
  std::map<std::string /*combondkey*/, CBondHisMarketstreamDealInfo>
      m_mapDealInfo;
};

/************************************************************************/
/* 所有历史成交数据集合                                                     */
/************************************************************************/
class S_BONDLIB_EXPORT CBondHisMarketstream {
 public:
  CBondHisMarketstream();
  ~CBondHisMarketstream();
  static CBondHisMarketstream& instance();

 public:
  /************************************************************************/
  /* 插入债券信息集合                                                        */
  /************************************************************************/
  bool InsertBondInfoList(xQBHisMarketstreamBond_Ack_c* pData);

  /************************************************************************/
  /* 插入债券成交集合                                                        */
  /************************************************************************/
  bool InsertBondDealList(xQBHisMarketstreamDeal_Ack_c* pData);

  /************************************************************************/
  /* 获取一天的数据                                                         */
  /************************************************************************/
  bool GetMarketStreamHisDay(int date, CBondHisMarketstreamDay& dayData);

 private:
  /************************************************************************/
  /* 某一天的数据                                                           */
  /************************************************************************/
  std::map<int /*####Y##M##D*/, CBondHisMarketstreamDay> m_mapDayData;

  qb::base::Mutex m_mutex;
};
